package com.cjb.cloudsystem.service.impl;

import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.cjb.cloudfabric.entity.BasicAsset;
import com.cjb.cloudfabric.entity.FabricUser;
import com.cjb.cloudfabric.service.OperateFabricService;
import com.cjb.cloudhdfs.api.HadoopUtil;
import com.cjb.cloudsystem.entity.FabricBasicAsset;
import com.cjb.cloudsystem.mapper.FabricBasicAssetMapper;
import com.cjb.cloudsystem.service.FabricBasicAssetService;
import com.cjb.cloudsystem.service.SysObjectService;
import com.cjb.cloudsystem.vo.FabricBasicAssetVO;
import com.cjb.common.exception.ServerException;
import com.cjb.common.mybatisUtil.impl.BaseRepositoryImpl;
import com.cjb.common.util.*;
import lombok.AllArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @Author chenjinbin
 * @Package IntelliJ IDEA
 * @Class FabricBasicAssetsServiceImpl
 * @Date 2023-07-27 21:41
 */
@Service
@AllArgsConstructor
public class FabricBasicAssetServiceImpl extends BaseRepositoryImpl<FabricBasicAssetMapper, FabricBasicAsset> implements FabricBasicAssetService {
    /**
     * 日志
     */
    private final static Logger log = LoggerFactory.getLogger(FabricBasicAssetServiceImpl.class);
    /*
     * 注入mapper层
     */
    private final FabricBasicAssetMapper fabricBasicAssetMapper;
    /**
     * 注入链码API
     */
    private final OperateFabricService operateFabricService;


    /**
     * 注入Hadoop API
     */
    private final HadoopUtil hadoopUtil;

    /**
     * fabric
     */
    private final String PREFIX = "FABRIC/";
    /**
     * 单体保存
     *
     * @Author chenjinbin
     * @Value
     * @Title
     */
    @Override
    public boolean save(FabricBasicAsset fabricBasicAsset) {
        if (Common.isEmpty(fabricBasicAsset.getId())){
            fabricBasicAsset.setId(String.valueOf(System.currentTimeMillis()));
            fabricBasicAsset.setUserId(String.valueOf(System.currentTimeMillis()));
        }
        if (Common.isEmpty(fabricBasicAsset)) {
            throw new ServerException("sysObject is empty");
        }

        BasicAsset asset = new BasicAsset();
        try {
            ChangeTypeUtil.copyNonNullProperties(fabricBasicAsset,asset);
        } catch (Throwable e) {
            log.info("复制异常，接着运行");
            throw new RuntimeException(e);
        }
        try {
            operateFabricService.SubmitAllAsset(asset);
            //服务证书生成
            FabricUser user = new FabricUser();
            if (Common.isNotEmpty(fabricBasicAsset.getUserId())){
                user.setUserName(fabricBasicAsset.getUserId());
            }
            if ((Common.isNotEmpty(fabricBasicAsset.getAppraisedValue()))){
                user.setAccount(String.valueOf(fabricBasicAsset.getAppraisedValue()));
            }
            if (Common.isNotEmpty(user)){
                log.info("生成证书");
                String path = operateFabricService.becomeCertificate(user);
                Optional.ofNullable(path)
                        .ifPresent(p ->{
                            try {
                                hadoopUtil.uploadFile(path,PREFIX+path);
                                log.info("打印要插入的文件{}", JsonUtils.toJsonString(PREFIX+path));
                                fabricBasicAsset.setDownloadPath(PREFIX+path);
                            } catch (Exception e) {
                                throw new RuntimeException(e);
                            }
                        });

            }

        } catch (Exception e) {
            log.info("上链码失败了");
            throw new ServerException("上链码失败了");
        }
        baseMapper.insert(fabricBasicAsset);
        log.info("插入数据成功");
        return true;
    }

    /**
     * 批量保存
     *
     * @Author chenjinbin
     * @Value
     * @Title
     */
    @Override
    public Integer listSave(List<FabricBasicAsset> fabricBasicAsset) {
        return baseMapper.insertBatchSomeColumn(fabricBasicAsset);
    }

    /**
     * 批量更新
     *
     * @Author chenjinbin
     * @Value
     * @Title
     */
    @Override
    public void listUpdate(List<FabricBasicAsset> fabricBasicAsset) {
        BasicAsset asset = new BasicAsset();
        try {
            ChangeTypeUtil.copyNonNullProperties(fabricBasicAsset,asset);
        } catch (Throwable e) {
            new ServerException("复制异常不管他就行");
        }
        try {
            operateFabricService.SubmitAllAsset(asset);
        } catch (Exception e) {
            new ServerException("更新失败");
            return;
        }
        saveOrUpdateBatch(fabricBasicAsset, fabricBasicAsset.size());
    }

    /**
     * 批量删除
     *
     * @Author chenjinbin
     * @Value
     * @Title
     */
    @Override
    public void listDelete(List<FabricBasicAsset> fabricBasicAsset) {
        fabricBasicAssetMapper.deleteBatchIds(fabricBasicAsset.stream().map(FabricBasicAsset::getId).distinct().collect(Collectors.toList()));
    }

    /**
     * 通过id删除
     *
     * @Author chenjinbin
     * @Value
     * @Title
     */
    @Override
    public int deleteById(FabricBasicAsset fabricBasicAsset) {
        if (Common.isEmpty(fabricBasicAsset) || Common.isEmpty(fabricBasicAsset.getId())){
            return -1;
        }
        try {
            operateFabricService.DeleteAsset(fabricBasicAsset.getId());
        } catch (Exception e) {
            new ServerException("链上删除失败");
            return  -1;
        }
        //return fabricBasicAssetMapper.deleteById(fabricBasicAsset.getId());
        fabricBasicAsset.setDeleted(Constant.NO);
        return fabricBasicAssetMapper.updateById(fabricBasicAsset);
    }

    /**
     * 单个查询
     *
     * @Author chenjinbin
     * @Value
     * @Title
     */
    @Override
    public FabricBasicAsset queryById(FabricBasicAsset fabricBasicAsset) {
        return fabricBasicAssetMapper.selectById(fabricBasicAsset.getId());
    }

    /**
     * 分页
     *
     * @Author chenjinbin
     * @Value
     * @Title
     */
    @Override
    public Page queryPage(Page fabricBasicAssetPage, FabricBasicAssetVO fabricBasicAssetVO) {
        return fabricBasicAssetMapper.selectPage(fabricBasicAssetPage, getWrapper(fabricBasicAssetVO));
    }

    /**
     * 查询属性
     *
     * @Author chenjinbin
     * @Value
     * @Title
     */
    private LambdaQueryWrapper<FabricBasicAsset> getWrapper(FabricBasicAssetVO query) {
        LambdaQueryWrapper<FabricBasicAsset> wrapper = Wrappers.lambdaQuery();
        if (Common.isNotNull(query.getId())) {
            wrapper.eq(FabricBasicAsset::getId, query.getId());
        }
        if (Common.isNotNull(query.getName())) {
            wrapper.like(FabricBasicAsset::getName, "%"+query.getName()+"%");
        }
        if (Common.isNotNull(query.getOwner())) {
            wrapper.like(FabricBasicAsset::getOwner, "%"+query.getOwner()+"%");
        }
        if (Common.isNotNull(query.getAppraisedValue())) {
            wrapper.eq(FabricBasicAsset::getAppraisedValue, query.getAppraisedValue());
        }
        if (Common.isNotNull(query.getUserId())) {
            wrapper.eq(FabricBasicAsset::getUserId, query.getUserId());
        }
        if (Common.isNotNull(query.getUpdateTime())) {
            wrapper.eq(FabricBasicAsset::getUpdateTime, query.getUpdateTime());
        }
        if (Common.isNotNull(query.getCreator())) {
            wrapper.eq(FabricBasicAsset::getCreator, query.getCreator());
        }
        if (Common.isNotNull(query.getDeleted())) {
            wrapper.eq(FabricBasicAsset::getDeleted, query.getDeleted());
        }
        if (Common.isNotNull(query.getUpdater())) {
            wrapper.eq(FabricBasicAsset::getUpdater, query.getUpdater());
        }
        if (Common.isNotNull(query.getCreateTime())) {
            wrapper.eq(FabricBasicAsset::getCreateTime, query.getCreateTime());
        }
        wrapper.orderByDesc(FabricBasicAsset::getId);
        return wrapper;
    }


    /**
     * 返回全部信息
     *
     * @Author chenjinbin
     * @Value
     * @Title
     */
    @Override
    public List<FabricBasicAsset> returnAllData() {
        return fabricBasicAssetMapper.selectList(null);
    }

    /**
     * 保持数据
     *
     * @Author chenjinbin
     * @Value
     * @Title
     */
    @Override
    public String saveBasic(FabricBasicAsset fabricBasicAsset) {
        if (Common.isEmpty(fabricBasicAsset.getId())){
            fabricBasicAsset.setId(String.valueOf(System.currentTimeMillis()));
            fabricBasicAsset.setUserId(String.valueOf(System.currentTimeMillis()));
        }
        if (Common.isEmpty(fabricBasicAsset)) {
            throw new ServerException("sysObject is empty");
        }

        BasicAsset asset = new BasicAsset();
        try {
            ChangeTypeUtil.copyNonNullProperties(fabricBasicAsset,asset);
        } catch (Throwable e) {
            log.info("复制异常，接着运行");
            throw new RuntimeException(e);
        }
        try {
            operateFabricService.SubmitAllAsset(asset);
            //服务证书生成
            FabricUser user = new FabricUser();
            if (Common.isNotEmpty(fabricBasicAsset.getUserId())){
                user.setUserName(fabricBasicAsset.getUserId());
            }
            if ((Common.isNotEmpty(fabricBasicAsset.getAppraisedValue()))){
                user.setAccount(String.valueOf(fabricBasicAsset.getAppraisedValue()));
            }
            if (Common.isNotEmpty(user)){
                log.info("生成证书");
                String path = operateFabricService.becomeCertificate(user);
                Optional.ofNullable(path)
                        .ifPresent(p ->{
                            try {
                                hadoopUtil.uploadFile(path,PREFIX+path);
                                log.info("打印要插入的文件{}", JsonUtils.toJsonString(PREFIX+path));
                                fabricBasicAsset.setDeleted(Constant.NO);
                                fabricBasicAsset.setDownloadPath(PREFIX+path);

                            } catch (Exception e) {
                                throw new RuntimeException(e);
                            }
                        });
                if (Common.isNotEmpty(fabricBasicAsset) &&Common.isEmpty(fabricBasicAsset.getCreateTime())){
                    fabricBasicAsset.setCreateTime(DateUtil.date().toTimestamp());
                }
                baseMapper.insert(fabricBasicAsset);
                log.info("插入数据成功");
                return PREFIX+path;
            }

        } catch (Exception e) {
            log.info("上链码失败了");
            throw new RuntimeException(e);
        }

        return "";
    }


}